# @Version        : 1.0
# @Update Time    : 2024/12/11 22:10
# @File           : menu_controller.py
# @IDE            : PyCharm
# @Desc           : 菜单视图
from fastapi import APIRouter, Depends
from fastapi_utils.cbv import cbv
from sqlalchemy import and_, false
from sqlalchemy.ext.asyncio import AsyncSession

from authx.dependencies.auth import RequireLogin
from authx.dependencies.permission import PermissionChecker
from src import schemas, models
from src.core.base_controller import BaseController
from src.core.dependencies import IdList
from src.core.response.response_schema import (
    ResponseGenericSchema,
    PageResponse,
)
from src.db.db_database import alchemy
from src.schemas.menu_schema import MenuTree, MenuParams
from src.services.menu_service import MenuService
from src.utils.toolsutils import ToolsUtils

router = APIRouter()


@cbv(router)
class MenuController(BaseController):
    """
    菜单视图
    """

    db: AsyncSession = Depends(alchemy.provide_session())
    menu_service: MenuService = Depends(alchemy.provide_service(MenuService))

    @router.get(
        "/list",
        summary="菜单列表",
        response_model=PageResponse[MenuTree],
        dependencies=[Depends(PermissionChecker("system:menu:list"))],
    )
    async def get_menu_list(self, param: MenuParams = Depends()):
        if not param.parent_id:
            return self.paginated_response(
                data=[], total=10, current=param.page, size=param.limit
            )
        where = await param.get_where(models.SysMenu)
        res, count = await self.menu_service.list_and_count(*where, param.limit_offset)
        return self.paginated_response(
            data=res, total=count, current=param.page, size=param.limit
        )

    @router.get(
        "/all",
        summary="菜单列表",
        response_model=ResponseGenericSchema[list[MenuTree]],
        dependencies=[Depends(PermissionChecker("system:menu:list"))],
    )
    async def get_menu_all(self):
        res = await self.menu_service.list(and_(models.SysMenu.menu_type != "3"))
        res = ToolsUtils.build_tree(
            [i.to_dict() for i in res],
            parent_id=None,
            parent_name="parent_id",
        )
        return self.success(data=res)

    # 获取所有页面
    @router.get(
        "/getAllPages",
        summary="获取所有页面",
        dependencies=[Depends(PermissionChecker("system:menu:list"))],
    )
    async def get_all_pages(self):
        res = await self.menu_service.list(and_(models.SysMenu.menu_type == "2"))
        page_list = [i.route_name for i in res]
        return self.success(data=page_list)

    @router.post(
        "/add",
        summary="创建菜单",
        description="创建菜单",
        dependencies=[Depends(PermissionChecker("system:menu:add"))],
    )
    async def add_menu(self, model: schemas.MenuCreate):
        await self.menu_service.create(
            model.model_dump(by_alias=False, exclude={"buttons"}),
            auto_commit=True,
        )
        return self.success(message="创建成功")

    @router.put(
        "/update",
        summary="更新菜单",
        description="更新菜单",
        dependencies=[Depends(PermissionChecker("system:menu:update"))],
    )
    async def update_menu(self, model: schemas.MenuUpdate):
        await self.menu_service.update(
            model.model_dump(exclude={"buttons"}),
            auto_commit=True,
        )
        return self.success(message="更新成功")

    @router.get(
        "/options",
        summary="菜单树状options",
        dependencies=[Depends(RequireLogin())],
    )
    async def get_menu_options(self):
        # 获取菜单树状options
        res = await self.menu_service.list(
            and_(models.SysMenu.status == "1", models.SysMenu.constant == false())
        )
        tree = ToolsUtils.options_tree(
            menu=[
                schemas.MenuUpdate.model_validate(i).model_dump(by_alias=True)
                for i in res
            ],
            parent_id=None,
            label="menuName",
            value="id",
        )
        return self.success(data=tree)

    # 查询菜单详情
    @router.get(
        "/view/{pk}",
        summary="查询菜单详情",
        dependencies=[Depends(PermissionChecker("system:menu:list"))],
        response_model=ResponseGenericSchema[schemas.MenuUpdate],
    )
    async def get_menu_view(self, pk: int):
        res = await self.menu_service.get_one(and_(models.SysMenu.id == pk))
        return self.success(data=res)

    @router.delete(
        "/delete",
        summary="删除菜单",
        description="删除菜单",
        dependencies=[Depends(PermissionChecker("system:menu:delete"))],
    )
    async def delete_menu(self, ids: IdList = Depends()):
        await self.menu_service.delete_many(ids.ids, auto_commit=True)
        return self.success(message="删除成功")
